package tasks

import (
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/logs"
	"lazyops_go/models"
	"lazyops_go/tools"
	"math"
	"strconv"
	"strings"
)

func SetHostConnect(user, password, host, key, cmd string, port int) bool {
	ciphers := []string{}
	session, err := tools.SSHConnect(user, password, host, key, port, ciphers)
	if err != nil {
		fmt.Println(err)
		return false
	}
	defer session.Close()
	//var stdoutBuf,stderrBuf bytes.Buffer
	//session.Stdout = &stdoutBuf
	//session.Stderr = &stderrBuf
	fmt.Println(cmd)
	ret, err := session.CombinedOutput(cmd)

	logs.Info(string(ret))
	if err != nil {
		return false
	}
	return true
}

func GetHostInfo(id int) bool {
	host_obj := models.QueryAssetOne(id)
	ip := host_obj.Ip
	// 获取服务器信息
	ret := tools.SaltRun(ip, "grains.items")
	js := []byte(ret)
	m := map[string]interface{}{}
	json.Unmarshal(js, &m)

	//获取磁盘分区信息
	ret_disk := tools.SaltRun(ip, "disk.usage")
	js_disk := []byte(ret_disk)
	m_disk := map[string]interface{}{}
	json.Unmarshal(js_disk, &m_disk)

	asset_os_obj := models.AssetOs{}
	nic_obj := models.AssetNic{}

	arp_cmd := "cat /etc/nginx/conf.d/* | grep server_name| grep -E '.com|.cn'| head -1|sed -n \"s/ *server_name *//p\" | sed -n \"s/;//p\""
	// 获取服务器信息
	host_apr := tools.SaltRunArgRet(ip, "cmd.run", arp_cmd, "root")
	var flag bool
	defer func() {
		if p := recover(); p != nil {
			fmt.Printf("panic recover! p: %v", p)
			flag = false
		}
	}()
	for _, v := range m["return"].([]interface{}) {
		for k, v1 := range v.(map[string]interface{}) {
			if k == ip {
				host_info := v1.(map[string]interface{})
				for z, v2 := range host_info {
					switch z {
					case "kernel":
						asset_os_obj.OsType = v2.(string)
					case "kernelrelease":
						asset_os_obj.KernelVersion = v2.(string)
					case "productname":
						asset_os_obj.ProductName = v2.(string)
					case "cpu_model":
						asset_os_obj.CPUModel = v2.(string)
					case "num_cpus":
						asset_os_obj.CPUCoreCount = int(v2.(float64))
					case "mem_total":
						asset_os_obj.MemorySize = int(math.Ceil(float64(v2.(float64) / 1024)))
					case "virtual":
						asset_os_obj.AssetType = v2.(string)
					case "lsb_distrib_codename":
						asset_os_obj.OsVersion = v2.(string)
					case "ip_interfaces":
						for zz, vv1 := range v2.(map[string]interface{}) {
							defer func() {
								if p := recover(); p != nil {
									fmt.Printf("panic recover! p: %v", p)
									flag = false
								}
							}()

							ip_list := vv1.([]interface{})
							for zz, vv1 := range ip_list {
								if zz == 0 {
									nic_obj.IpAddr = vv1.(string)
								} else {
									nic_obj.Mac = vv1.(string)
								}
							}
							nic_obj.NicName = zz
							nic_obj.AssetId = id
							models.AddAssetNic(nic_obj)
						}

					}

				}
			}
		}
	}
	asset_os_obj.AssetId = id
	asset_os_obj.HostArp = host_apr
	models.AddAssetOS(asset_os_obj)

	disk_obj := models.AssetPartitions{}
	for _, v := range m_disk["return"].([]interface{}) {
		for k, v1 := range v.(map[string]interface{}) {
			if k == ip {
				disk_info := v1.(map[string]interface{})
				for z, v2 := range disk_info {
					disk_obj.Mount = z
					for zz, vv := range v2.(map[string]interface{}) {
						switch zz {
						case "1K-blocks":
							size_total, _ := strconv.Atoi((vv.(string)))
							disk_obj.SizeTotal = int(math.Ceil(float64(size_total / 1024)))
						case "available":
							size_avl, _ := strconv.Atoi((vv.(string)))
							disk_obj.SizeAvaileble = int(math.Ceil(float64(size_avl / 1024)))
						case "filesystem":
							disk_obj.Partition = vv.(string)
						}
						disk_obj.AssetId = id
					}
					models.AddAssetPart(disk_obj)
				}
			}
		}
	}
	flag = true
	return flag
}

func CodeRelease(release_host, cmd_web, cmd, dest_host, version string, id int) string {
	_ = tools.SaltRunArgRet(release_host, "cmd.run", cmd_web, "root")
	ret := tools.SaltRunArgRet(release_host, "cmd.run", cmd, "root")
	if ret == "SUCCESS" {
		obj := models.QueryReleaseOne(id)
		//如果发布成功，发送邮件通知
		ret_sp := strings.Split(version, "/")
		body := fmt.Sprintf("%s\n{code_path,      \"%s\"}\n{code_version,  \"%s\"}", dest_host, ret_sp[0], ret_sp[1])

		email_obj, err := models.QueryDictKey("NOTICE_EMAIL")
		if err != nil {
			fmt.Println("NOTICE_EMAIL:通知邮箱地址未配置")
		} else {
			send_email := email_obj.DictVal
			tools.SendMail(send_email, "【"+obj.Platfm.Prj.PrjName+"】版本发布", body, "")
		}
		obj.Status = false
		models.UpdateRelease(id, obj)
	}
	return ret
}

func DeployScript(ip_list, script_file, args string) string {
	salt_file := fmt.Sprintf("salt://%s", script_file)
	var ret string
	if args == "" {
		ret = tools.SaltRunArg(ip_list, "cmd.script", salt_file, "root")

	} else {
		ret = tools.SaltRunArgs(ip_list, "cmd.script", salt_file, args, "root")
	}
	js := []byte(ret)
	m := map[string]interface{}{}
	json.Unmarshal(js, &m)
	ret_str := ""
	for _, v := range m["return"].([]interface{}) {
		for k, v1 := range v.(map[string]interface{}) {
			ret_str += fmt.Sprintf("=================== %s （SUCCESS）===================\nScript：%s\nResult：\n%s\n\n", k, script_file, v1)
		}
	}
	return ret
}

func UpdateTestServer(test_url string) string {
	ret := tools.GetReq(test_url)
	return ret
}
